using UnityEngine;
using UI.BankingPanel.Data;
using UI.Common;
using System.Linq;
using System.Collections.Generic;

namespace UI.BankingPanel
{
    /// <summary>
    /// 坐庄收款系统控制器类
    /// 负责初始化BankingData和BankingView，使用DataModel进行数据驱动
    /// </summary>
    public class BankingCtrl : MonoBehaviour
    {
        #region 组件引用
        [Header("MVC组件")]
        [SerializeField] private BankingData model;
        [SerializeField] private BankingView view;
        #endregion

        #region 数据模型
        [Header("响应式数据模型")]
        private ValueModel<StatisticsData> statisticsModel;
        private ValueModel<float> revenueModel;
        private ValueModel<float> eatCodeTotalModel;
        private ValueModel<float> reportTotalModel;
        private ValueModel<float> oddsModel;
        
        // 新增：平均吃码和最大亏损数据模型
        private ValueModel<float> averageEatCodeModel;
        private ValueModel<float> maxLossLimitModel;
        
        // 观察者ID，用于取消监听
        private WatcherId statisticsWatcherId;
        private WatcherId revenueWatcherId;
        private WatcherId eatCodeWatcherId;
        private WatcherId reportWatcherId;
        private WatcherId oddsWatcherId;
        private WatcherId averageEatCodeWatcherId;
        private WatcherId maxLossLimitWatcherId;
        #endregion

        #region 初始化
        /// <summary>
        /// 初始化控制器
        /// </summary>
        public void Initialize()
        {
            InitializeModel();
            InitializeDataModels();
            InitializeView();
            BindDataToView();
            
            // 数据加载完成后，刷新统计信息以确保显示正确的数据
            RefreshStatistics();
        }

        /// <summary>
        /// 初始化数据模型
        /// </summary>
        private void InitializeModel()
        {
            // 从数据管理器获取持久化的数据
            if (BankingDataManager.Instance != null)
            {
                model = BankingDataManager.Instance.BankingData;
                Debug.Log("[BankingCtrl] 从数据管理器加载银行数据");
            }
            else
            {
                // 如果没有数据管理器，创建默认数据
                if (model == null)
                {
                    model = new BankingData();
                }
                Debug.LogWarning("[BankingCtrl] 数据管理器未找到，使用默认数据");
            }
        }

        /// <summary>
        /// 初始化响应式数据模型
        /// </summary>
        private void InitializeDataModels()
        {
            // 从加载的数据中获取实际的统计信息
            var actualStats = model.GetStatisticsData();
            
            // 创建响应式数据模型，使用实际数据而不是默认值
            statisticsModel = DataModel.CreateValue<StatisticsData>(actualStats);
            revenueModel = DataModel.CreateValue<float>(actualStats.revenueTotal);
            eatCodeTotalModel = DataModel.CreateValue<float>(actualStats.eatCodeTotal);
            reportTotalModel = DataModel.CreateValue<float>(actualStats.reportTotal);
            oddsModel = DataModel.CreateValue<float>(actualStats.odds);
            
            // 新增：平均吃码和最大亏损数据模型，使用BankingData中的实际值
            averageEatCodeModel = DataModel.CreateValue<float>(model.averageBetAmount);
            maxLossLimitModel = DataModel.CreateValue<float>(model.maxLossLimit);
            
            Debug.Log($"[BankingCtrl] 数据模型初始化完成 - 收款总数:{actualStats.revenueTotal}, 吃码总数:{actualStats.eatCodeTotal}, 上报总数:{actualStats.reportTotal}, 赔率:{actualStats.odds}");
        }

        /// <summary>
        /// 初始化视图
        /// </summary>
        private void InitializeView()
        {
            if (view == null)
            {
                view = GetComponent<BankingView>();
                if (view == null)
                {
                    view = gameObject.AddComponent<BankingView>();
                }
            }
            
            view.Initialize();
        }

        /// <summary>
        /// 绑定数据模型到视图
        /// </summary>
        private void BindDataToView()
        {
            var headerStats = view.GetHeaderStatistics();
            if (headerStats == null)
            {
                Debug.LogError("HeaderStatistics component not found!");
                return;
            }

            // 绑定输入事件监听
            BindHeaderStatisticsEvents(headerStats);

            // 初始化列表数据
            InitializeBetScrollView();
            
            // 初始化风险数据列表
            InitializeRiskDataScrollView();

            // 监听统计数据变化，同步到界面
            statisticsWatcherId = statisticsModel.AddWatcher((statsData, isChange) =>
            {
                if (isChange && statsData != null)
                {
                    // 获取当前的号码数据用于风险统计
                    var numberBetDataList = model.GetAllNumberBetData();
                    headerStats.UpdateStatisticsDisplay(statsData, numberBetDataList);
                    Debug.Log($"Statistics updated: Revenue={statsData.revenueTotal}, EatCode={statsData.eatCodeTotal}, Report={statsData.reportTotal}, Odds={statsData.odds}");
                }
            }, true);

            // 监听平均吃码数据变化
            averageEatCodeWatcherId = averageEatCodeModel.AddWatcher((value, isChange) =>
            {
                if (isChange)
                {
                    headerStats.SetAverageEatCodeDisplay(value);
                    Debug.Log($"Average EatCode updated: {value}");
                }
            }, true); // 立即触发一次，显示初始值

            // 监听最大亏损数据变化
            maxLossLimitWatcherId = maxLossLimitModel.AddWatcher((value, isChange) =>
            {
                if (isChange)
                {
                    headerStats.SetMaxLossLimitDisplay(value);
                    Debug.Log($"Max Loss Limit updated: {value}");
                }
            }, true); // 立即触发一次，显示初始值
        }

        /// <summary>
        /// 绑定头部统计组件的输入事件
        /// </summary>
        private void BindHeaderStatisticsEvents(UI.BankingPanel.Components.C_Header_Statistics headerStats)
        {
            // 监听平均吃码输入变化
            headerStats.OnAverageEatCodeChanged += OnAverageEatCodeInputChanged;
            
            // 监听最大亏损输入变化
            headerStats.OnMaxLossLimitChanged += OnMaxLossLimitInputChanged;
            
            Debug.Log("[BankingCtrl] 头部统计组件事件绑定完成");
        }

        /// <summary>
        /// 初始化押注列表视图
        /// </summary>
        private void InitializeBetScrollView()
        {
            var betScrollView = view.GetBetScrollView();
            if (betScrollView == null)
            {
                Debug.LogError("BetScrollView component not found!");
                return;
            }

            Debug.Log("[BankingCtrl] 开始初始化押注列表数据...");

            // 设置数据变化回调
            betScrollView.SetBetDataFieldChangedCallback(OnBetDataFieldChanged);

            // 设置初始数据（49个号码）
            var betDataList = model.GetAllNumberBetData();
            Debug.Log($"[BankingCtrl] 设置列表数据，数量: {betDataList.Count}");
            
            betScrollView.SetBetDataList(betDataList);
            
            Debug.Log("[BankingCtrl] 押注列表初始化完成");
        }

        /// <summary>
        /// 初始化风险数据列表视图
        /// </summary>
        private void InitializeRiskDataScrollView()
        {
            var riskScrollView = view.GetRiskDataScrollView();
            if (riskScrollView == null)
            {
                Debug.LogWarning("[BankingCtrl] 风险数据列表组件未找到，跳过初始化");
                return;
            }

            Debug.Log("[BankingCtrl] 开始初始化风险数据列表...");

            // 初始化风险数据列表
            riskScrollView.Initialize(OnRiskItemSelected);

            // 设置排序方式为按风险值排序（亏损大的在前）
            riskScrollView.SetSortType(UI.BankingPanel.Components.C_RiskData_ScrollView.RiskSortType.ByRiskValue, false);

            // 设置初始数据
            var betDataList = model.GetAllNumberBetData();
            riskScrollView.SetRiskDataList(betDataList);

            Debug.Log("[BankingCtrl] 风险数据列表初始化完成");
        }

        /// <summary>
        /// 风险项目选择回调
        /// </summary>
        /// <param name="betData">选中的押注数据</param>
        private void OnRiskItemSelected(UI.BankingPanel.Data.NumberBetData betData)
        {
            Debug.Log($"[BankingCtrl] 选中号码: {betData.number}, 风险值: {betData.riskValue}");
            
            // 可以在这里添加更多的业务逻辑，比如：
            // 1. 跳转到对应的押注项
            // 2. 显示详细的风险分析
            // 3. 提供风险处理建议
            
            // 显示号码信息
            string message = $"号码 {betData.number:D2}\n风险值: {betData.riskValue:0.##}";
            Color messageColor = betData.riskValue < -5000f ? Color.red : Color.white;
            ToastSystem.ShowToast(message, messageColor);
        }
        #endregion

        #region 输入事件处理 - 业务逻辑层
        /// <summary>
        /// 平均吃码输入变化处理
        /// </summary>
        private void OnAverageEatCodeInputChanged(float value)
        {
            Debug.Log($"[BankingCtrl] 处理平均吃码输入: {value}");
            
            // 更新数据模型和BankingData
            averageEatCodeModel.Set(value);
            model.averageBetAmount = value;
            
            // 业务逻辑：应用平均吃码到所有号码
            ApplyAverageEatCodeToAllNumbers(value);
            
            // 自动保存数据
            if (BankingDataManager.Instance != null)
            {
                BankingDataManager.Instance.AutoSaveBankingData();
            }
            
            // 显示提示
            ToastSystem.ShowToast($"平均吃码已设置: {value}", 1.5f);
        }

        /// <summary>
        /// 最大亏损输入变化处理
        /// </summary>
        private void OnMaxLossLimitInputChanged(float value)
        {
            Debug.Log($"[BankingCtrl] 处理最大亏损输入: {value}");
            
            // 更新数据模型和BankingData
            maxLossLimitModel.Set(value);
            model.maxLossLimit = value;
            
            // 业务逻辑：设置最大亏损限制
            SetMaxLossLimit(value);
            
            // 自动保存数据
            if (BankingDataManager.Instance != null)
            {
                BankingDataManager.Instance.AutoSaveBankingData();
            }
            
            // 显示提示
            ToastSystem.ShowToast($"最大亏损已设置: {value}", 1.5f);
        }

        /// <summary>
        /// 应用平均吃码到所有号码
        /// </summary>
        private void ApplyAverageEatCodeToAllNumbers(float averageEatCode)
        {
            Debug.Log($"[BankingCtrl] 开始应用平均吃码 {averageEatCode} 到所有号码");
            
            var allBetData = model.GetAllNumberBetData();
            int updatedCount = 0;
            int riskAdjustedCount = 0;
            float maxLossLimit = GetMaxLossLimit();
            
            // 第一步：应用平均吃码
            foreach (var betData in allBetData)
            {
                // 只对有总押注的号码应用平均吃码
                if (betData.totalBetAmount > 0)
                {
                    // 有总押注的号码：吃码不能超过总押注，且必须是整数
                    int averageEatCodeInt = Mathf.FloorToInt(averageEatCode);
                    betData.selfBetAmount = Mathf.Min(averageEatCodeInt, betData.totalBetAmount);
                    updatedCount++;
                    
                    Debug.Log($"[BankingCtrl] 更新号码{betData.number}: 总押注{betData.totalBetAmount}, 设置吃码{betData.selfBetAmount}");
                }
                else
                {
                    // 没有总押注的号码：吃码保持为0
                    betData.selfBetAmount = 0;
                    Debug.Log($"[BankingCtrl] 号码{betData.number}: 总押注为0，吃码保持为0");
                }
                
                betData.UpdateReportAmount();
                
                // 更新模型数据（会自动触发风险值重新计算）
                model.UpdateNumberBetData(betData.number, betData);
            }
            
            // 第二步：检查风险值并调整（如果设置了最大亏损限制）
            if (maxLossLimit > 0)
            {
                Debug.Log($"[BankingCtrl] 检查风险值，最大亏损限制: {maxLossLimit}");
                
                // 重新计算所有风险值
                model.RecalculateAllRiskValues();
                
                foreach (var betData in allBetData)
                {
                    if (betData.totalBetAmount > 0 && betData.riskValue < -maxLossLimit)
                    {
                        float oldEatCode = betData.selfBetAmount;
                        
                        // 风险值超过限制，需要调整吃码
                        // 目标：让风险值刚好等于 -maxLossLimit
                        // 风险值公式：总吃码 - 该号码吃码*赔率 = -maxLossLimit
                        // 即：该号码吃码*赔率 = 总吃码 + maxLossLimit
                        
                        // 计算当前所有号码的总吃码
                        float totalEatCode = allBetData.Sum(b => b.selfBetAmount);
                        
                        // 计算目标吃码：(总吃码 + 最大亏损) / 赔率
                        float targetEatCode = (totalEatCode + maxLossLimit) / model.odds;
                        
                        // 确保不超过总押注，且是整数
                        targetEatCode = Mathf.Min(targetEatCode, betData.totalBetAmount);
                        targetEatCode = Mathf.Max(0, Mathf.Floor(targetEatCode));
                        
                        if (Mathf.Abs(oldEatCode - targetEatCode) > 0.01f)
                        {
                            betData.selfBetAmount = targetEatCode;
                            betData.UpdateReportAmount();
                            model.UpdateNumberBetData(betData.number, betData);
                            riskAdjustedCount++;
                            
                            Debug.Log($"[BankingCtrl] 风险调整号码{betData.number:D2}: 风险值{betData.riskValue:F2} -> 目标{-maxLossLimit:F2}, 吃码 {oldEatCode:F2} -> {targetEatCode:F2}");
                        }
                    }
                }
                
                // 如果有调整，重新计算风险值
                if (riskAdjustedCount > 0)
                {
                    model.RecalculateAllRiskValues();
                }
            }
            
            // 刷新列表显示
            RefreshBetScrollViewDisplay();
            
            // 刷新风险数据列表
            RefreshRiskDataDisplay();
            
            // 刷新统计数据
            RefreshStatistics();
            
            Debug.Log($"[BankingCtrl] 平均吃码应用完成，实际更新了 {updatedCount} 个有总押注的号码");
            
            if (riskAdjustedCount > 0)
            {
                Debug.Log($"[BankingCtrl] 风险调整完成，调整了 {riskAdjustedCount} 个号码的吃码以符合最大亏损限制");
                ToastSystem.ShowToast($"已更新 {updatedCount} 个号码，其中 {riskAdjustedCount} 个进行了风险调整", 3.0f);
            }
            else
            {
                ToastSystem.ShowToast($"已更新 {updatedCount} 个有总押注号码的吃码", 1.0f);
            }
        }

        /// <summary>
        /// 设置最大亏损限制 - 吃码自适应设置
        /// </summary>
        private void SetMaxLossLimit(float maxLoss)
        {
            Debug.Log($"[BankingCtrl] 设置最大亏损限制: {maxLoss}，开始自适应调整吃码");
            
            var allBetData = model.GetAllNumberBetData();
            int adjustedCount = 0;
            
            // 记录调整前的状态
            var originalEatCodes = new Dictionary<int, float>();
            foreach (var betData in allBetData)
            {
                originalEatCodes[betData.number] = betData.selfBetAmount;
            }
            
            // 更新模型中的最大亏损限制
            model.maxLossLimit = maxLoss;
            
            // 如果最大亏损限制为0，表示不限制，使用平均吃码
            if (maxLoss <= 0)
            {
                Debug.Log($"[BankingCtrl] 最大亏损限制为0，使用平均吃码设置");
                ApplyAverageEatCodeToAllNumbers(GetAverageEatCode());
                return;
            }
            
            // 自适应计算每个号码的吃码
            foreach (var betData in allBetData)
            {
                if (betData.totalBetAmount > 0)
                {
                    float oldEatCode = betData.selfBetAmount;
                    
                    // 计算基于最大亏损限制的理论最大吃码
                    // 风险值公式：总吃码 - 该号码吃码*赔率 >= -最大亏损
                    // 即：该号码吃码*赔率 <= 总吃码 + 最大亏损
                    // 但这里需要考虑所有号码的总吃码，所以我们使用一个简化的方法：
                    // 每个号码的最大吃码 = 最大亏损 / 赔率
                    float maxAllowedEatCode = maxLoss / model.odds;
                    
                    // 获取平均吃码作为参考
                    float averageEatCode = GetAverageEatCode();
                    
                    // 选择较小的值作为目标吃码（不超过总押注）
                    float targetEatCode = Mathf.Min(
                        Mathf.Min(maxAllowedEatCode, averageEatCode),
                        betData.totalBetAmount
                    );
                    
                    // 确保不为负数，并向下取整到最小单位1
                    targetEatCode = Mathf.Max(0, Mathf.Floor(targetEatCode));
                    
                    // 应用新的吃码
                    betData.selfBetAmount = targetEatCode;
                    betData.UpdateReportAmount();
                    
                    if (Mathf.Abs(oldEatCode - targetEatCode) > 0.01f)
                    {
                        adjustedCount++;
                        Debug.Log($"[BankingCtrl] 自适应调整号码{betData.number:D2}: 吃码 {oldEatCode:F2} -> {targetEatCode:F2} (最大允许:{maxAllowedEatCode:F2}, 平均:{averageEatCode:F2})");
                    }
                }
            }
            
            // 重新计算所有号码的风险值
            model.RecalculateAllRiskValues();
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            // 显示调整结果
            if (adjustedCount > 0)
            {
                Debug.Log($"[BankingCtrl] 最大亏损限制自适应调整完成，调整了 {adjustedCount} 个号码的吃码");
                ToastSystem.ShowToast($"最大亏损限制已设置，自适应调整了 {adjustedCount} 个号码的吃码", 3.0f);
            }
            else
            {
                Debug.Log($"[BankingCtrl] 最大亏损限制设置完成，无需调整");
                ToastSystem.ShowToast($"最大亏损限制已设置: {maxLoss}", 2.0f);
            }
        }
        #endregion

        #region 数据变化回调
        /// <summary>
        /// 押注数据字段变化回调
        /// </summary>
        /// <param name="numberId">号码ID</param>
        /// <param name="fieldType">字段类型</param>
        /// <param name="newValue">新值</param>
        private void OnBetDataFieldChanged(int numberId, UI.BankingPanel.Components.BetDataFieldType fieldType, float newValue)
        {
            Debug.Log($"[BankingCtrl] 押注数据字段变化 - 号码{numberId}, 字段{fieldType}, 新值{newValue}");
            
            // 获取当前数据
            var currentData = model.GetNumberData(numberId);
            if (currentData == null)
            {
                Debug.LogError($"[BankingCtrl] 未找到号码{numberId}的数据");
                return;
            }
            
            // 获取当前平均吃码设置
            float currentAverageEatCode = GetAverageEatCode();
            
            // 根据字段类型更新对应的值
            switch (fieldType)
            {
                case UI.BankingPanel.Components.BetDataFieldType.TotalBet:
                    currentData.totalBetAmount = newValue;
                    
                    // 智能计算吃码
                    if (newValue <= 0)
                    {
                        // 总押注为0或负数时，吃码也应该为0
                        currentData.selfBetAmount = 0;
                    }
                    else if (currentAverageEatCode > 0)
                    {
                        // 有平均吃码设置时：使用平均吃码，但不能超过总押注，且必须是整数
                        int averageEatCodeInt = Mathf.FloorToInt(currentAverageEatCode);
                        currentData.selfBetAmount = Mathf.Min(averageEatCodeInt, newValue);
                    }
                    else
                    {
                        // 没有设置平均吃码时：保持原有吃码不变，但不能超过总押注
                        currentData.selfBetAmount = Mathf.Min(currentData.selfBetAmount, newValue);
                    }
                    
                    // 重新计算上报数量
                    currentData.UpdateReportAmount();
                    
                    Debug.Log($"[BankingCtrl] 总押注更新 - 号码{numberId}: 总押注{newValue}, 自动设置吃码{currentData.selfBetAmount}, 上报{currentData.reportAmount}");
                    break;
                    
                case UI.BankingPanel.Components.BetDataFieldType.EatCode:
                    // 吃码必须是整数，且不能超过总押注
                    int eatCodeInt = Mathf.FloorToInt(newValue);
                    float maxAllowedEatCode = currentData.totalBetAmount;
                    currentData.selfBetAmount = Mathf.Min(eatCodeInt, maxAllowedEatCode);
                    
                    // 用户手动设置吃码时，更新原始吃码记录
                    if (currentData.selfBetAmount > 0)
                    {
                        currentData.originalEatCode = currentData.selfBetAmount;
                    }
                    
                    if (newValue != eatCodeInt)
                    {
                        Debug.LogWarning($"[BankingCtrl] 吃码取整 - 号码{numberId}: 输入{newValue}, 调整为整数{eatCodeInt}");
                        ToastSystem.ShowToast($"号码{numberId:D2} 吃码已调整为整数: {eatCodeInt}", 2.0f);
                    }
                    else if (eatCodeInt > maxAllowedEatCode)
                    {
                        Debug.LogWarning($"[BankingCtrl] 吃码超限 - 号码{numberId}: 输入{eatCodeInt}, 最大允许{maxAllowedEatCode}, 已调整为{currentData.selfBetAmount}");
                        ToastSystem.ShowToast($"号码{numberId:D2} 吃码不能超过总押注，已调整为{currentData.selfBetAmount}", 2.0f);
                    }
                    
                    // 重新计算上报数量
                    currentData.UpdateReportAmount();
                    break;
                    
                case UI.BankingPanel.Components.BetDataFieldType.Report:
                    // 上报必须是整数
                    int reportInt = Mathf.FloorToInt(newValue);
                    currentData.reportAmount = reportInt;
                    
                    // 根据上报数量反推吃码 (总押注 - 上报 = 吃码)
                    currentData.selfBetAmount = currentData.totalBetAmount - reportInt;
                    
                    // 确保吃码不为负数，并且是整数
                    if (currentData.selfBetAmount < 0)
                    {
                        currentData.selfBetAmount = 0;
                        currentData.reportAmount = currentData.totalBetAmount;
                        Debug.LogWarning($"[BankingCtrl] 上报超限 - 号码{numberId}: 上报不能超过总押注，已调整");
                        ToastSystem.ShowToast($"号码{numberId:D2} 上报不能超过总押注，已调整", 2.0f);
                    }
                    else
                    {
                        // 确保反推的吃码也是整数
                        currentData.selfBetAmount = Mathf.Floor(currentData.selfBetAmount);
                        // 重新计算上报（因为吃码可能被取整了）
                        currentData.reportAmount = currentData.totalBetAmount - currentData.selfBetAmount;
                    }
                    
                    if (newValue != reportInt)
                    {
                        Debug.LogWarning($"[BankingCtrl] 上报取整 - 号码{numberId}: 输入{newValue}, 调整为整数{reportInt}");
                        ToastSystem.ShowToast($"号码{numberId:D2} 上报已调整为整数: {reportInt}", 2.0f);
                    }
                    break;
            }
            
            // 更新模型数据（这会自动触发所有号码的风险值重新计算）
            model.UpdateNumberBetData(numberId, currentData);
            
            // 刷新列表显示（确保UI显示最新的计算结果）
            RefreshBetScrollViewDisplay();
            
            // 刷新风险数据列表
            RefreshRiskDataDisplay();
            
            // 刷新统计数据
            RefreshStatistics();
            
            // 自动保存数据
            if (BankingDataManager.Instance != null)
            {
                BankingDataManager.Instance.AutoSaveBankingData();
            }
            
            // 显示提示信息
            string fieldName = GetFieldDisplayName(fieldType);
            ToastSystem.ShowToast($"号码{numberId:D2} {fieldName}: {currentData.GetFieldValue(fieldType)}", 1.5f);
            
            Debug.Log($"[BankingCtrl] 号码{numberId}数据更新完成: 总押注{currentData.totalBetAmount}, 吃码{currentData.selfBetAmount}, 上报{currentData.reportAmount}, 风险值{currentData.riskValue}");
        }

        /// <summary>
        /// 获取字段显示名称
        /// </summary>
        /// <param name="fieldType">字段类型</param>
        /// <returns>显示名称</returns>
        private string GetFieldDisplayName(UI.BankingPanel.Components.BetDataFieldType fieldType)
        {
            switch (fieldType)
            {
                case UI.BankingPanel.Components.BetDataFieldType.TotalBet:
                    return "总押注";
                case UI.BankingPanel.Components.BetDataFieldType.EatCode:
                    return "吃码";
                case UI.BankingPanel.Components.BetDataFieldType.Report:
                    return "上报";
                default:
                    return "未知字段";
            }
        }
        #endregion

        #region 测试方法
        /// <summary>
        /// 测试方法：设置一些测试数据
        /// </summary>
        [ContextMenu("设置测试数据")]
        public void SetTestData()
        {
            Debug.Log("[BankingCtrl] 设置测试数据...");
            
            // 设置前几个号码的测试数据
            for (int i = 0; i < 10; i++)
            {
                var betData = model.GetAllNumberBetData()[i];
                betData.totalBetAmount = UnityEngine.Random.Range(100f, 500f);
                betData.selfBetAmount = UnityEngine.Random.Range(50f, 200f);
                betData.UpdateReportAmount();
                betData.CalculateRiskValue(model.odds, model.GetAllNumberBetData());
                
                // 使用号码ID而不是索引
                model.UpdateNumberBetData(betData.number, betData);
                Debug.Log($"[BankingCtrl] 测试数据 - 号码{betData.number}: 总押注{betData.totalBetAmount}, 自己吃码{betData.selfBetAmount}");
            }
            
            // 刷新列表显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            
            // 刷新统计数据
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 测试数据设置完成");
        }

        /// <summary>
        /// 测试方法：测试平均吃码功能
        /// </summary>
        [ContextMenu("测试平均吃码功能")]
        public void TestAverageEatCode()
        {
            Debug.Log("[BankingCtrl] 开始测试平均吃码功能...");
            
            // 先设置一些总押注数据
            for (int i = 0; i < 5; i++)
            {
                var betData = model.GetAllNumberBetData()[i];
                betData.totalBetAmount = 100f;
                betData.selfBetAmount = 0f;
                betData.UpdateReportAmount();
                model.UpdateNumberBetData(betData.number, betData);
            }
            
            // 设置平均吃码为1
            OnAverageEatCodeInputChanged(1f);
            
            Debug.Log("[BankingCtrl] 平均吃码测试完成");
        }

        /// <summary>
        /// 测试方法：测试新的风险值计算逻辑
        /// </summary>
        [ContextMenu("测试风险值计算逻辑")]
        public void TestRiskValueCalculation()
        {
            Debug.Log("[BankingCtrl] 开始测试风险值计算逻辑...");
            
            // 设置测试数据
            var allBetData = model.GetAllNumberBetData();
            
            // 1号：吃码 50
            allBetData[0].totalBetAmount = 100f;
            allBetData[0].selfBetAmount = 50f;
            
            // 2号：吃码 30
            allBetData[1].totalBetAmount = 80f;
            allBetData[1].selfBetAmount = 30f;
            
            // 3号：吃码 20
            allBetData[2].totalBetAmount = 60f;
            allBetData[2].selfBetAmount = 20f;
            
            // 4号：吃码 10
            allBetData[3].totalBetAmount = 40f;
            allBetData[3].selfBetAmount = 10f;
            
            // 5号：吃码 0
            allBetData[4].totalBetAmount = 20f;
            allBetData[4].selfBetAmount = 0f;
            
            // 重新计算所有风险值
            foreach (var betData in allBetData.Take(5))
            {
                betData.UpdateReportAmount();
                betData.CalculateRiskValue(model.odds, model.GetAllNumberBetData());
                model.UpdateNumberBetData(betData.number, betData);
            }
            
            // 输出计算结果
            Debug.Log("=== 风险值计算结果 ===");
            Debug.Log($"赔率: {model.odds}");
            
            float totalOtherBets = allBetData.Take(5).Sum(b => b.totalBetAmount);
            Debug.Log($"所有号码总押注: {totalOtherBets}");
            
            foreach (var betData in allBetData.Take(5))
            {
                float otherTotalBets = allBetData.Take(5).Where(b => b.number != betData.number).Sum(b => b.totalBetAmount);
                float payout = betData.totalBetAmount * model.odds;
                float expectedRisk = otherTotalBets - payout;
                
                Debug.Log($"号码{betData.number:D2}: 总押注{betData.totalBetAmount}, 其他号码总押注{otherTotalBets}, 赔付{payout}, 预期风险{expectedRisk}, 实际风险{betData.riskValue}");
            }
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 风险值计算逻辑测试完成");
        }

        /// <summary>
        /// 测试方法：测试1-6号相同押注的风险值计算
        /// </summary>
        [ContextMenu("测试1-6号相同押注风险值")]
        public void TestSameBetRiskValue()
        {
            Debug.Log("[BankingCtrl] 开始测试1-6号相同押注风险值...");
            
            // 设置测试数据：1-6号都是总押注10
            var allBetData = model.GetAllNumberBetData();
            
            for (int i = 0; i < 6; i++)
            {
                allBetData[i].totalBetAmount = 10f;
                allBetData[i].selfBetAmount = 10f; // 全部自己吃
                allBetData[i].UpdateReportAmount();
            }
            
            // 其他号码设为0
            for (int i = 6; i < allBetData.Count; i++)
            {
                allBetData[i].totalBetAmount = 0f;
                allBetData[i].selfBetAmount = 0f;
                allBetData[i].UpdateReportAmount();
            }
            
            // 重新计算所有风险值
            foreach (var betData in allBetData)
            {
                betData.CalculateRiskValue(model.odds, model.GetAllNumberBetData());
                model.UpdateNumberBetData(betData.number, betData);
            }
            
            // 输出1-6号的计算结果
            Debug.Log("=== 1-6号相同押注风险值计算结果 ===");
            Debug.Log($"赔率: {model.odds}");
            Debug.Log($"每个号码总押注: 10, 吃码: 10");
            
            float allTotalBets = 10 * 6; // 所有6个号码的总押注
            Debug.Log($"所有号码总押注: {allTotalBets}");
            
            for (int i = 0; i < 6; i++)
            {
                var betData = allBetData[i];
                float payout = betData.selfBetAmount * model.odds; // 该号码赔付（基于吃码）
                float expectedRisk = allTotalBets - payout;
                
                Debug.Log($"号码{betData.number:D2}: 总押注{betData.totalBetAmount}, 吃码{betData.selfBetAmount}, 赔付{payout}, 预期风险{expectedRisk}, 实际风险{betData.riskValue}");
            }
            
            // 验证1-6号风险值是否相同
            bool allSame = true;
            float firstRiskValue = allBetData[0].riskValue;
            for (int i = 1; i < 6; i++)
            {
                if (Mathf.Abs(allBetData[i].riskValue - firstRiskValue) > 0.01f)
                {
                    allSame = false;
                    break;
                }
            }
            
            Debug.Log($"1-6号风险值是否相同: {allSame}");
            Debug.Log($"共同风险值: {firstRiskValue}");
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 1-6号相同押注风险值测试完成");
        }

        /// <summary>
        /// 测试方法：测试没有吃码的风险值计算
        /// </summary>
        [ContextMenu("测试没有吃码的风险值")]
        public void TestNoEatCodeRiskValue()
        {
            Debug.Log("[BankingCtrl] 开始测试没有吃码的风险值...");
            
            // 设置测试数据
            var allBetData = model.GetAllNumberBetData();
            
            // 1-3号有总押注但没有吃码
            for (int i = 0; i < 3; i++)
            {
                allBetData[i].totalBetAmount = 100f;
                allBetData[i].selfBetAmount = 0f; // 没有吃码
                allBetData[i].UpdateReportAmount();
            }
            
            // 4-6号有总押注也有吃码
            for (int i = 3; i < 6; i++)
            {
                allBetData[i].totalBetAmount = 100f;
                allBetData[i].selfBetAmount = 50f; // 有吃码
                allBetData[i].UpdateReportAmount();
            }
            
            // 其他号码设为0
            for (int i = 6; i < allBetData.Count; i++)
            {
                allBetData[i].totalBetAmount = 0f;
                allBetData[i].selfBetAmount = 0f;
                allBetData[i].UpdateReportAmount();
            }
            
            // 重新计算所有风险值
            foreach (var betData in allBetData)
            {
                betData.CalculateRiskValue(model.odds, model.GetAllNumberBetData());
                model.UpdateNumberBetData(betData.number, betData);
            }
            
            // 输出计算结果
            Debug.Log("=== 没有吃码的风险值计算结果 ===");
            Debug.Log($"赔率: {model.odds}");
            
            float allTotalBets = 100 * 6; // 所有6个号码的总押注
            Debug.Log($"所有号码总押注: {allTotalBets}");
            
            for (int i = 0; i < 6; i++)
            {
                var betData = allBetData[i];
                float payout = betData.selfBetAmount * model.odds;
                float expectedRisk = betData.selfBetAmount > 0 ? allTotalBets - payout : 0f;
                
                Debug.Log($"号码{betData.number:D2}: 总押注{betData.totalBetAmount}, 吃码{betData.selfBetAmount}, 赔付{payout}, 预期风险{expectedRisk}, 实际风险{betData.riskValue}");
            }
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 没有吃码的风险值测试完成");
        }

        /// <summary>
        /// 测试方法：验证用户示例的风险值计算
        /// </summary>
        [ContextMenu("测试用户示例风险值计算")]
        public void TestUserExampleRiskValueCalculation()
        {
            Debug.Log("[BankingCtrl] 开始测试用户示例的风险值计算...");
            
            // 重置所有数据
            model.ResetAllData();
            
            // 设置用户示例数据
            // 1号：总押注10，吃码10
            var bet1 = model.GetNumberData(1);
            bet1.totalBetAmount = 10f;
            bet1.selfBetAmount = 10f;
            bet1.UpdateReportAmount();
            model.UpdateNumberBetData(1, bet1);
            
            // 2号：总押注10，吃码10
            var bet2 = model.GetNumberData(2);
            bet2.totalBetAmount = 10f;
            bet2.selfBetAmount = 10f;
            bet2.UpdateReportAmount();
            model.UpdateNumberBetData(2, bet2);
            
            // 3号：总押注100，吃码5
            var bet3 = model.GetNumberData(3);
            bet3.totalBetAmount = 100f;
            bet3.selfBetAmount = 5f;
            bet3.UpdateReportAmount();
            model.UpdateNumberBetData(3, bet3);
            
            Debug.Log("=== 用户示例数据设置完成 ===");
            
            // 计算预期值
            float allEatCodeTotal = 10f + 10f + 5f; // = 25
            Debug.Log($"所有号码吃码总和: {allEatCodeTotal}");
            
            // 验证风险值计算
            Debug.Log("=== 风险值验证（按用户示例） ===");
            
            // 01号
            var bet1Data = model.GetNumberData(1);
            float expected1Risk = allEatCodeTotal - (bet1Data.selfBetAmount * model.odds);
            Debug.Log($"01号: 吃码={bet1Data.selfBetAmount}, 预期风险值={expected1Risk}, 实际风险值={bet1Data.riskValue}, 匹配={Mathf.Abs(expected1Risk - bet1Data.riskValue) < 0.01f}");
            
            // 02号
            var bet2Data = model.GetNumberData(2);
            float expected2Risk = allEatCodeTotal - (bet2Data.selfBetAmount * model.odds);
            Debug.Log($"02号: 吃码={bet2Data.selfBetAmount}, 预期风险值={expected2Risk}, 实际风险值={bet2Data.riskValue}, 匹配={Mathf.Abs(expected2Risk - bet2Data.riskValue) < 0.01f}");
            
            // 03号
            var bet3Data = model.GetNumberData(3);
            float expected3Risk = allEatCodeTotal - (bet3Data.selfBetAmount * model.odds);
            Debug.Log($"03号: 吃码={bet3Data.selfBetAmount}, 预期风险值={expected3Risk}, 实际风险值={bet3Data.riskValue}, 匹配={Mathf.Abs(expected3Risk - bet3Data.riskValue) < 0.01f}");
            
            // 04号（没有吃码）
            var bet4Data = model.GetNumberData(4);
            float expected4Risk = allEatCodeTotal - (bet4Data.selfBetAmount * model.odds);
            Debug.Log($"04号: 吃码={bet4Data.selfBetAmount}, 预期风险值={expected4Risk}, 实际风险值={bet4Data.riskValue}, 匹配={Mathf.Abs(expected4Risk - bet4Data.riskValue) < 0.01f}");
            
            // 验证计算公式
            Debug.Log("=== 计算公式验证 ===");
            Debug.Log($"01号风险值 = {allEatCodeTotal} - ({bet1Data.selfBetAmount} × {model.odds}) = {allEatCodeTotal} - {bet1Data.selfBetAmount * model.odds} = {expected1Risk}");
            Debug.Log($"02号风险值 = {allEatCodeTotal} - ({bet2Data.selfBetAmount} × {model.odds}) = {allEatCodeTotal} - {bet2Data.selfBetAmount * model.odds} = {expected2Risk}");
            Debug.Log($"03号风险值 = {allEatCodeTotal} - ({bet3Data.selfBetAmount} × {model.odds}) = {allEatCodeTotal} - {bet3Data.selfBetAmount * model.odds} = {expected3Risk}");
            Debug.Log($"04号风险值 = {allEatCodeTotal} - ({bet4Data.selfBetAmount} × {model.odds}) = {allEatCodeTotal} - {bet4Data.selfBetAmount * model.odds} = {expected4Risk}");
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 用户示例风险值计算测试完成");
        }

        /// <summary>
        /// 测试方法：验证修正后的风险值计算逻辑
        /// </summary>
        [ContextMenu("测试修正后的风险值计算")]
        public void TestCorrectedRiskValueCalculation()
        {
            Debug.Log("[BankingCtrl] 开始测试修正后的风险值计算逻辑...");
            
            // 重置所有数据
            model.ResetAllData();
            
            // 设置测试数据：模拟图片中的情况
            // 1-6号：总押注10，吃码10
            for (int i = 1; i <= 6; i++)
            {
                var betData = model.GetNumberData(i);
                betData.totalBetAmount = 10f;
                betData.selfBetAmount = 10f;
                betData.UpdateReportAmount();
                model.UpdateNumberBetData(i, betData);
            }
            
            // 第8号：总押注1000，吃码107
            var bet8 = model.GetNumberData(8);
            bet8.totalBetAmount = 1000f;
            bet8.selfBetAmount = 107f;
            bet8.UpdateReportAmount();
            model.UpdateNumberBetData(8, bet8);
            
            Debug.Log("=== 测试数据设置完成 ===");
            
            // 计算预期值
            float allTotalBets = 10f * 6 + 1000f; // = 1060
            Debug.Log($"所有号码总押注: {allTotalBets}");
            
            // 验证风险值计算
            Debug.Log("=== 风险值验证 ===");
            
            // 1-6号（有吃码）
            for (int i = 1; i <= 6; i++)
            {
                var betData = model.GetNumberData(i);
                float expectedRisk = allTotalBets - (betData.selfBetAmount * model.odds);
                Debug.Log($"号码{i:D2}: 吃码={betData.selfBetAmount}, 预期风险值={expectedRisk}, 实际风险值={betData.riskValue}, 匹配={Mathf.Abs(expectedRisk - betData.riskValue) < 0.01f}");
            }
            
            // 第8号（有吃码）
            var bet8Data = model.GetNumberData(8);
            float expected8Risk = allTotalBets - (bet8Data.selfBetAmount * model.odds);
            Debug.Log($"号码08: 吃码={bet8Data.selfBetAmount}, 预期风险值={expected8Risk}, 实际风险值={bet8Data.riskValue}, 匹配={Mathf.Abs(expected8Risk - bet8Data.riskValue) < 0.01f}");
            
            // 其他号码（没有吃码）
            Debug.Log("=== 没有吃码的号码风险值验证 ===");
            for (int i = 7; i <= 12; i++)
            {
                if (i == 8) continue; // 跳过第8号
                
                var betData = model.GetNumberData(i);
                float expectedRisk = allTotalBets; // 没有吃码，风险值应该等于总押注
                Debug.Log($"号码{i:D2}: 吃码={betData.selfBetAmount}, 预期风险值={expectedRisk}, 实际风险值={betData.riskValue}, 匹配={Mathf.Abs(expectedRisk - betData.riskValue) < 0.01f}");
            }
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 修正后的风险值计算测试完成");
        }

        /// <summary>
        /// 测试方法：验证风险值重新计算逻辑
        /// </summary>
        [ContextMenu("测试风险值重新计算")]
        public void TestRiskValueRecalculation()
        {
            Debug.Log("[BankingCtrl] 开始测试风险值重新计算逻辑...");
            
            // 设置测试数据：1-6号都是总押注10，吃码10
            for (int i = 1; i <= 6; i++)
            {
                var betData = model.GetNumberData(i);
                betData.totalBetAmount = 10f;
                betData.selfBetAmount = 10f;
                betData.UpdateReportAmount();
                model.UpdateNumberBetData(i, betData);
            }
            
            Debug.Log("=== 初始设置后的风险值 ===");
            for (int i = 1; i <= 6; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 修改第7号的数据，看是否会影响其他号码的风险值
            Debug.Log("=== 修改第7号数据 ===");
            var bet7 = model.GetNumberData(7);
            bet7.totalBetAmount = 20f;
            bet7.selfBetAmount = 15f;
            bet7.UpdateReportAmount();
            model.UpdateNumberBetData(7, bet7);
            
            Debug.Log("=== 修改第7号后所有号码的风险值 ===");
            for (int i = 1; i <= 8; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 验证计算是否正确
            float allTotalBets = 0f;
            for (int i = 1; i <= 49; i++)
            {
                allTotalBets += model.GetNumberData(i).totalBetAmount;
            }
            
            Debug.Log($"=== 验证计算 ===");
            Debug.Log($"所有号码总押注: {allTotalBets}");
            
            for (int i = 1; i <= 8; i++)
            {
                var betData = model.GetNumberData(i);
                if (betData.selfBetAmount > 0)
                {
                    float expectedRisk = allTotalBets - (betData.selfBetAmount * model.odds);
                    Debug.Log($"号码{i:D2}: 预期风险值={expectedRisk}, 实际风险值={betData.riskValue}, 匹配={Mathf.Abs(expectedRisk - betData.riskValue) < 0.01f}");
                }
                else
                {
                    Debug.Log($"号码{i:D2}: 没有吃码，风险值应为0, 实际风险值={betData.riskValue}");
                }
            }
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 风险值重新计算测试完成");
        }

        /// <summary>
        /// 测试方法：验证智能恢复以赚得更多为准的逻辑
        /// </summary>
        [ContextMenu("测试智能恢复以赚得更多为准")]
        public void TestSmartRecoveryForMaxProfit()
        {
            Debug.Log("[BankingCtrl] 开始测试智能恢复以赚得更多为准的逻辑...");
            
            // 重置所有数据
            model.ResetAllData();
            
            // 设置平均吃码为100（较小的值）
            OnAverageEatCodeInputChanged(100f);
            
            // 设置测试数据：1-3号都有总押注
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                betData.totalBetAmount = 500f;
                betData.selfBetAmount = 300f; // 初始吃码300（比平均吃码大）
                betData.UpdateReportAmount();
                model.UpdateNumberBetData(i, betData);
            }
            
            Debug.Log("=== 初始状态 ===");
            Debug.Log($"平均吃码设置: {GetAverageEatCode()}");
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 第一步：设置最大亏损限制为0（应该把所有吃码设为0）
            Debug.Log("=== 第一步：设置最大亏损限制为0 ===");
            SetMaxLossLimit(0f);
            
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 第二步：设置最大亏损限制为5000（应该智能恢复，选择更大的目标）
            Debug.Log("=== 第二步：设置最大亏损限制为5000（智能恢复，以赚得更多为准） ===");
            SetMaxLossLimit(5000f);
            
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 验证恢复结果：应该选择更大的目标（基于最大亏损限制的目标 vs 平均吃码100）
            Debug.Log("=== 分析恢复结果 ===");
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                float averageTarget = 100f; // 平均吃码目标
                
                // 计算基于最大亏损限制的目标
                float currentEatCodeTotal = 0f;
                for (int j = 1; j <= 3; j++)
                {
                    currentEatCodeTotal += model.GetNumberData(j).selfBetAmount;
                }
                float maxLossTarget = (currentEatCodeTotal + 5000f) / model.odds;
                
                Debug.Log($"号码{i:D2}: 平均吃码目标={averageTarget}, 最大亏损限制目标={maxLossTarget:F0}, 实际恢复={betData.selfBetAmount}");
                Debug.Log($"选择了更大的目标: {(betData.selfBetAmount > averageTarget ? "是" : "否")}");
            }
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 智能恢复以赚得更多为准的测试完成");
        }

        /// <summary>
        /// 测试方法：验证基本的智能恢复功能
        /// </summary>
        [ContextMenu("测试基本智能恢复功能")]
        public void TestBasicSmartRecovery()
        {
            Debug.Log("[BankingCtrl] 开始测试基本智能恢复功能...");
            
            // 重置所有数据
            model.ResetAllData();
            
            // 设置平均吃码为200
            OnAverageEatCodeInputChanged(200f);
            
            // 设置测试数据：1-3号都有总押注
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                betData.totalBetAmount = 300f;
                betData.selfBetAmount = 200f; // 初始吃码200
                betData.UpdateReportAmount();
                model.UpdateNumberBetData(i, betData);
            }
            
            Debug.Log("=== 初始状态 ===");
            Debug.Log($"平均吃码设置: {GetAverageEatCode()}");
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 第一步：设置最大亏损限制为0（应该把所有吃码设为0）
            Debug.Log("=== 第一步：设置最大亏损限制为0 ===");
            SetMaxLossLimit(0f);
            
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 第二步：设置最大亏损限制为10000（应该智能恢复吃码）
            Debug.Log("=== 第二步：设置最大亏损限制为10000（智能恢复） ===");
            SetMaxLossLimit(10000f);
            
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 验证恢复结果
            bool recoveryWorked = true;
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                if (betData.selfBetAmount < 200f) // 应该恢复到200或更多
                {
                    recoveryWorked = false;
                    break;
                }
            }
            
            Debug.Log($"=== 智能恢复测试结果: {(recoveryWorked ? "成功" : "失败")} ===");
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 基本智能恢复功能测试完成");
        }

        /// <summary>
        /// 测试方法：验证用户描述的具体场景
        /// </summary>
        [ContextMenu("测试用户场景：限制50→40→50")]
        public void TestUserScenario()
        {
            Debug.Log("[BankingCtrl] 开始测试用户场景：限制50→40→50...");
            
            // 重置所有数据
            model.ResetAllData();
            
            // 设置1号的数据：下注1
            var bet1 = model.GetNumberData(1);
            bet1.totalBetAmount = 1f;
            bet1.selfBetAmount = 0f; // 先设为0
            bet1.UpdateReportAmount();
            model.UpdateNumberBetData(1, bet1);
            
            Debug.Log("=== 初始状态：1号下注1 ===");
            Debug.Log($"号码01: 总押注={bet1.totalBetAmount}, 吃码={bet1.selfBetAmount}, 上报={bet1.reportAmount}, 风险值={bet1.riskValue}");
            
            // 第一步：设置最大亏损限制为50
            Debug.Log("=== 第一步：限制最大亏损50 ===");
            SetMaxLossLimit(50f);
            
            // 手动设置1号吃码为1（模拟用户操作）
            bet1 = model.GetNumberData(1);
            bet1.selfBetAmount = 1f;
            bet1.originalEatCode = 1f; // 记录原始值
            bet1.UpdateReportAmount();
            model.UpdateNumberBetData(1, bet1);
            
            Debug.Log($"设置1号吃码为1后: 总押注={bet1.totalBetAmount}, 吃码={bet1.selfBetAmount}, 上报={bet1.reportAmount}, 风险值={bet1.riskValue}");
            
            // 第二步：限制最大亏损40（应该把吃码调整为0）
            Debug.Log("=== 第二步：限制最大亏损40 ===");
            SetMaxLossLimit(40f);
            
            bet1 = model.GetNumberData(1);
            Debug.Log($"限制40后: 总押注={bet1.totalBetAmount}, 吃码={bet1.selfBetAmount}, 上报={bet1.reportAmount}, 风险值={bet1.riskValue}");
            
            // 第三步：恢复限制最大亏损50（应该智能恢复吃码为1）
            Debug.Log("=== 第三步：恢复限制最大亏损50（智能恢复） ===");
            SetMaxLossLimit(50f);
            
            bet1 = model.GetNumberData(1);
            Debug.Log($"恢复50后: 总押注={bet1.totalBetAmount}, 吃码={bet1.selfBetAmount}, 上报={bet1.reportAmount}, 风险值={bet1.riskValue}");
            
            // 验证结果
            bool recoveryWorked = (bet1.selfBetAmount >= 1f);
            Debug.Log($"=== 智能恢复测试结果: {(recoveryWorked ? "成功" : "失败")} ===");
            Debug.Log($"期望: 吃码应该恢复到1, 实际: 吃码={bet1.selfBetAmount}");
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 用户场景测试完成");
        }

        /// <summary>
        /// 测试方法：验证最大亏损限制的智能恢复功能
        /// </summary>
        [ContextMenu("测试最大亏损限制智能恢复")]
        public void TestMaxLossLimitSmartRecovery()
        {
            Debug.Log("[BankingCtrl] 开始测试最大亏损限制智能恢复功能...");
            
            // 重置所有数据
            model.ResetAllData();
            
            // 设置平均吃码为10
            OnAverageEatCodeInputChanged(10f);
            
            // 设置测试数据：1-3号都有总押注
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                betData.totalBetAmount = 10f;
                betData.selfBetAmount = 10f; // 初始吃码为10
                betData.UpdateReportAmount();
                model.UpdateNumberBetData(i, betData);
            }
            
            Debug.Log("=== 初始状态 ===");
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 第一步：设置最大亏损限制为0（应该把所有吃码设为0）
            Debug.Log("=== 设置最大亏损限制为0 ===");
            OnMaxLossLimitInputChanged(0f);
            
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 第二步：设置最大亏损限制为300（应该智能恢复吃码）
            Debug.Log("=== 设置最大亏损限制为300（智能恢复） ===");
            OnMaxLossLimitInputChanged(300f);
            
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 验证恢复结果
            Debug.Log("=== 验证智能恢复结果 ===");
            bool recoverySuccess = true;
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                if (betData.selfBetAmount <= 0)
                {
                    recoverySuccess = false;
                    Debug.LogError($"号码{i:D2} 吃码恢复失败，仍为0");
                }
                else
                {
                    Debug.Log($"号码{i:D2} 吃码成功恢复为 {betData.selfBetAmount}");
                }
            }
            
            if (recoverySuccess)
            {
                Debug.Log("✅ 智能恢复功能测试成功！");
                ToastSystem.ShowToast("智能恢复功能测试成功！", 2.0f);
            }
            else
            {
                Debug.LogError("❌ 智能恢复功能测试失败！");
                ToastSystem.ShowToast("智能恢复功能测试失败！", 2.0f);
            }
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 最大亏损限制智能恢复测试完成");
        }

        /// <summary>
        /// 测试方法：验证平均吃码风险调整功能
        /// </summary>
        [ContextMenu("测试平均吃码风险调整")]
        public void TestAverageEatCodeRiskAdjustment()
        {
            Debug.Log("[BankingCtrl] 开始测试平均吃码风险调整功能...");
            
            // 重置所有数据
            model.ResetAllData();
            
            // 设置测试环境
            model.odds = 47f;
            model.maxLossLimit = 40f; // 设置最大亏损限制为40
            
            Debug.Log($"=== 测试环境设置 ===");
            Debug.Log($"赔率: {model.odds}");
            Debug.Log($"最大亏损限制: {model.maxLossLimit}");
            
            // 设置测试数据：1号有总押注
            var betData1 = model.GetNumberData(1);
            betData1.totalBetAmount = 100f;
            betData1.selfBetAmount = 0f;
            model.UpdateNumberBetData(1, betData1);
            
            Debug.Log($"=== 初始数据 ===");
            Debug.Log($"号码01: 总押注={betData1.totalBetAmount}, 吃码={betData1.selfBetAmount}");
            
            // 设置平均吃码为1（这会导致风险值为-47，超过限制-40）
            Debug.Log($"=== 应用平均吃码1 ===");
            ApplyAverageEatCodeToAllNumbers(1f);
            
            // 检查结果
            betData1 = model.GetNumberData(1);
            Debug.Log($"应用平均吃码后:");
            Debug.Log($"号码01: 总押注={betData1.totalBetAmount}, 吃码={betData1.selfBetAmount}, 风险值={betData1.riskValue}");
            
            // 预期结果：
            // 如果风险值为-47，超过了限制-40，系统应该调整吃码
            // 目标风险值：-40
            // 风险值公式：总吃码 - 该号码吃码*赔率 = -40
            // 即：1 - 吃码*47 = -40
            // 吃码 = (1 + 40) / 47 ≈ 0.87，向下取整为0
            
            if (betData1.riskValue >= -model.maxLossLimit)
            {
                Debug.Log($"✓ 测试通过：风险值{betData1.riskValue}在限制范围内（>= {-model.maxLossLimit}）");
            }
            else
            {
                Debug.LogError($"✗ 测试失败：风险值{betData1.riskValue}超过限制{-model.maxLossLimit}");
            }
            
            // 测试2：设置更大的平均吃码
            Debug.Log($"=== 测试2：应用平均吃码10 ===");
            ApplyAverageEatCodeToAllNumbers(10f);
            
            betData1 = model.GetNumberData(1);
            Debug.Log($"应用平均吃码10后:");
            Debug.Log($"号码01: 总押注={betData1.totalBetAmount}, 吃码={betData1.selfBetAmount}, 风险值={betData1.riskValue}");
            
            // 预期：风险值应该被调整到接近-40
            
            Debug.Log("[BankingCtrl] 平均吃码风险调整功能测试完成");
        }

        /// <summary>
        /// 测试方法：验证整数单位处理
        /// </summary>
        [ContextMenu("测试整数单位处理")]
        public void TestIntegerUnitHandling()
        {
            Debug.Log("[BankingCtrl] 开始测试整数单位处理...");
            
            // 重置所有数据
            model.ResetAllData();
            
            // 测试1：设置带小数的平均吃码
            Debug.Log("=== 测试1：平均吃码小数处理 ===");
            OnAverageEatCodeInputChanged(123.7f);
            
            // 设置一些总押注
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                betData.totalBetAmount = 500f;
                betData.selfBetAmount = 0f;
                model.UpdateNumberBetData(i, betData);
            }
            
            // 应用平均吃码
            ApplyAverageEatCodeToAllNumbers(123.7f);
            
            // 检查结果
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 吃码={betData.selfBetAmount} (应该是123)");
            }
            
            // 测试2：设置带小数的最大亏损限制
            Debug.Log("=== 测试2：最大亏损限制小数处理 ===");
            SetMaxLossLimit(2500.8f);
            
            // 检查结果
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 吃码={betData.selfBetAmount} (应该是整数)");
            }
            
            // 测试3：手动输入带小数的吃码
            Debug.Log("=== 测试3：手动吃码小数处理 ===");
            OnBetDataFieldChanged(1, UI.BankingPanel.Components.BetDataFieldType.EatCode, 45.9f);
            
            var testData = model.GetNumberData(1);
            Debug.Log($"号码01: 吃码={testData.selfBetAmount} (应该是45)");
            
            // 测试4：手动输入带小数的上报
            Debug.Log("=== 测试4：手动上报小数处理 ===");
            OnBetDataFieldChanged(2, UI.BankingPanel.Components.BetDataFieldType.Report, 456.3f);
            
            var testData2 = model.GetNumberData(2);
            Debug.Log($"号码02: 上报={testData2.reportAmount} (应该是456), 吃码={testData2.selfBetAmount} (应该是整数)");
            
            Debug.Log("[BankingCtrl] 整数单位处理测试完成");
        }

        /// <summary>
        /// 测试方法：验证最大亏损限制的自适应吃码功能
        /// </summary>
        [ContextMenu("测试最大亏损自适应吃码")]
        public void TestMaxLossAdaptiveEatCode()
        {
            Debug.Log("[BankingCtrl] 开始测试最大亏损自适应吃码功能...");
            
            // 重置所有数据
            model.ResetAllData();
            
            // 设置平均吃码为200
            OnAverageEatCodeInputChanged(200f);
            
            // 设置测试数据：1-3号都有总押注
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                betData.totalBetAmount = 500f;
                betData.selfBetAmount = 0f; // 初始吃码为0
                betData.UpdateReportAmount();
                model.UpdateNumberBetData(i, betData);
            }
            
            Debug.Log("=== 初始状态 ===");
            Debug.Log($"平均吃码设置: {GetAverageEatCode()}");
            Debug.Log($"赔率: {model.odds}");
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 测试1：设置最大亏损限制为1000（较小值）
            Debug.Log("=== 测试1：设置最大亏损限制为1000 ===");
            OnMaxLossLimitInputChanged(1000f);
            
            float maxAllowedByLoss1 = 1000f / model.odds; // 约21.28
            Debug.Log($"基于最大亏损1000的理论最大吃码: {maxAllowedByLoss1:F2}");
            Debug.Log($"平均吃码: {GetAverageEatCode()}");
            Debug.Log($"应该选择较小值: {Mathf.Min(maxAllowedByLoss1, GetAverageEatCode()):F2}");
            
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 测试2：设置最大亏损限制为10000（较大值）
            Debug.Log("=== 测试2：设置最大亏损限制为10000 ===");
            OnMaxLossLimitInputChanged(10000f);
            
            float maxAllowedByLoss2 = 10000f / model.odds; // 约212.77
            Debug.Log($"基于最大亏损10000的理论最大吃码: {maxAllowedByLoss2:F2}");
            Debug.Log($"平均吃码: {GetAverageEatCode()}");
            Debug.Log($"应该选择较小值: {Mathf.Min(maxAllowedByLoss2, GetAverageEatCode()):F2}");
            
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 测试3：设置最大亏损限制为0（不限制）
            Debug.Log("=== 测试3：设置最大亏损限制为0（不限制） ===");
            OnMaxLossLimitInputChanged(0f);
            
            Debug.Log($"最大亏损限制为0，应该使用平均吃码: {GetAverageEatCode()}");
            
            for (int i = 1; i <= 3; i++)
            {
                var betData = model.GetNumberData(i);
                Debug.Log($"号码{i:D2}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue}");
            }
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log("[BankingCtrl] 最大亏损自适应吃码测试完成");
            ToastSystem.ShowToast("最大亏损自适应吃码测试完成", 2.0f);
        }

        /// <summary>
        /// 测试盈亏统计功能
        /// </summary>
        [ContextMenu("测试盈亏统计")]
        public void TestRiskStatistics()
        {
            Debug.Log("[BankingCtrl] 开始测试盈亏统计功能...");
            
            // 设置一些测试数据
            var allBetData = model.GetAllNumberBetData();
            
            // 设置前5个号码有不同的风险值
            allBetData[0].totalBetAmount = 100; allBetData[0].selfBetAmount = 50; // 号码1
            allBetData[1].totalBetAmount = 200; allBetData[1].selfBetAmount = 100; // 号码2
            allBetData[2].totalBetAmount = 150; allBetData[2].selfBetAmount = 75; // 号码3
            allBetData[3].totalBetAmount = 300; allBetData[3].selfBetAmount = 200; // 号码4
            allBetData[4].totalBetAmount = 80; allBetData[4].selfBetAmount = 40; // 号码5
            
            // 更新数据并重新计算风险值
            for (int i = 0; i < 5; i++)
            {
                allBetData[i].UpdateReportAmount();
                model.UpdateNumberBetData(allBetData[i].number, allBetData[i]);
            }
            
            // 刷新统计显示
            RefreshStatistics();
            
            // 输出风险值信息用于调试
            Debug.Log("=== 风险值统计测试结果 ===");
            int winCount = 0, loseCount = 0;
            foreach (var betData in allBetData)
            {
                if (betData.totalBetAmount > 0)
                {
                    Debug.Log($"号码{betData.number}: 总押注={betData.totalBetAmount}, 吃码={betData.selfBetAmount}, 风险值={betData.riskValue:F2}");
                    if (betData.riskValue > 0) winCount++;
                    else if (betData.riskValue < 0) loseCount++;
                }
            }
            Debug.Log($"统计结果: 盈余个数={winCount}, 亏损个数={loseCount}");
            
            ToastSystem.ShowToast($"盈亏统计测试完成\n盈余:{winCount} 亏损:{loseCount}", 3.0f);
        }

        /// <summary>
        /// 修复方法：重置所有无效的吃码数据
        /// </summary>
        [ContextMenu("修复吃码数据")]
        public void FixEatCodeData()
        {
            Debug.Log("[BankingCtrl] 开始修复吃码数据...");
            
            var allBetData = model.GetAllNumberBetData();
            int fixedCount = 0;
            
            foreach (var betData in allBetData)
            {
                // 如果总押注为0但吃码不为0，则修复
                if (betData.totalBetAmount <= 0 && betData.selfBetAmount > 0)
                {
                    betData.selfBetAmount = 0;
                    betData.UpdateReportAmount();
                    model.UpdateNumberBetData(betData.number, betData);
                    fixedCount++;
                    
                    Debug.Log($"[BankingCtrl] 修复号码{betData.number}: 总押注{betData.totalBetAmount}, 吃码重置为0");
                }
                // 如果吃码超过总押注，则修复
                else if (betData.selfBetAmount > betData.totalBetAmount)
                {
                    betData.selfBetAmount = betData.totalBetAmount;
                    betData.UpdateReportAmount();
                    model.UpdateNumberBetData(betData.number, betData);
                    fixedCount++;
                    
                    Debug.Log($"[BankingCtrl] 修复号码{betData.number}: 吃码从{betData.selfBetAmount}调整为{betData.totalBetAmount}");
                }
            }
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            Debug.Log($"[BankingCtrl] 吃码数据修复完成，修复了 {fixedCount} 个号码");
            ToastSystem.ShowToast($"已修复 {fixedCount} 个号码的吃码数据", 2.0f);
        }
        #endregion

        #region 数据更新方法
        /// <summary>
        /// 更新号码押注数据
        /// </summary>
        public void UpdateNumberBet(int number, float totalBet, float selfBet)
        {
            model.UpdateNumberBet(number, totalBet, selfBet);
            RefreshStatistics();
        }

        /// <summary>
        /// 刷新统计数据
        /// </summary>
        public void RefreshStatistics()
        {
            var statsData = model.GetStatisticsData();
            statisticsModel.Set(statsData);
            
            // 同时更新单独的数据模型
            revenueModel.Set(statsData.revenueTotal);
            eatCodeTotalModel.Set(statsData.eatCodeTotal);
            reportTotalModel.Set(statsData.reportTotal);
            oddsModel.Set(statsData.odds);
        }

        /// <summary>
        /// 刷新押注列表显示
        /// </summary>
        private void RefreshBetScrollViewDisplay()
        {
            var betScrollView = view.GetBetScrollView();
            if (betScrollView != null)
            {
                betScrollView.SetBetDataList(model.GetAllNumberBetData());
                Debug.Log("[BankingCtrl] 押注列表显示已刷新");
            }
        }

        /// <summary>
        /// 刷新风险数据列表显示
        /// </summary>
        private void RefreshRiskDataDisplay()
        {
            var riskScrollView = view.GetRiskDataScrollView();
            if (riskScrollView != null)
            {
                riskScrollView.SetRiskDataList(model.GetAllNumberBetData());
                Debug.Log("[BankingCtrl] 风险数据列表显示已刷新");
            }
        }

        /// <summary>
        /// 设置赔率
        /// </summary>
        public void SetOdds(float newOdds)
        {
            model.odds = newOdds;
            oddsModel.Set(newOdds);
            
            // 重新计算所有号码的风险值（因为赔率变化会影响风险值）
            model.RecalculateAllRiskValues();
            
            // 刷新显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            // 自动保存数据
            if (BankingDataManager.Instance != null)
            {
                BankingDataManager.Instance.AutoSaveBankingData();
            }
        }

        /// <summary>
        /// 重置所有数据
        /// </summary>
        public void ResetAllData()
        {
            model.ResetAllData();
            
            // 重置输入数据模型和BankingData中的设置为默认值
            averageEatCodeModel.Set(206f);
            model.averageBetAmount = 206f;
            maxLossLimitModel.Set(4000f);
            model.maxLossLimit = 4000f;
            
            // 刷新所有显示
            RefreshBetScrollViewDisplay();
            RefreshRiskDataDisplay();
            RefreshStatistics();
            
            // 保存重置后的数据
            if (BankingDataManager.Instance != null)
            {
                BankingDataManager.Instance.SaveBankingData();
            }
        }
        #endregion

        #region 数据获取方法
        /// <summary>
        /// 获取当前统计数据
        /// </summary>
        public StatisticsData GetCurrentStatistics()
        {
            return statisticsModel.Get();
        }

        /// <summary>
        /// 获取庄家数据模型
        /// </summary>
        public BankingData GetBankingData()
        {
            return model;
        }
        
        /// <summary>
        /// 导出数据到Excel
        /// </summary>
        /// <param name="fileName">自定义文件名（可选）</param>
        /// <returns>导出结果</returns>
        public ExportResult ExportToExcel(string fileName = null)
        {
            return ExportToExcel(fileName, ExportFormat.Detailed);
        }
        
        /// <summary>
        /// 导出数据到Excel（支持格式选择）
        /// </summary>
        /// <param name="fileName">自定义文件名（可选）</param>
        /// <param name="format">导出格式</param>
        /// <returns>导出结果</returns>
        public ExportResult ExportToExcel(string fileName, ExportFormat format)
        {
            if (model == null)
            {
                return new ExportResult(false, "数据模型为空，无法导出");
            }
            
            return ExcelExporter.ExportBankingDataToExcel(model, fileName, format);
        }

        /// <summary>
        /// 获取当前平均吃码设置
        /// </summary>
        public float GetAverageEatCode()
        {
            return averageEatCodeModel.Get();
        }

        /// <summary>
        /// 获取当前最大亏损限制
        /// </summary>
        public float GetMaxLossLimit()
        {
            return maxLossLimitModel.Get();
        }
        #endregion

        #region 生命周期
        private void OnDestroy()
        {
            // 取消事件监听
            var headerStats = view?.GetHeaderStatistics();
            if (headerStats != null)
            {
                headerStats.OnAverageEatCodeChanged -= OnAverageEatCodeInputChanged;
                headerStats.OnMaxLossLimitChanged -= OnMaxLossLimitInputChanged;
            }
            
            // 取消所有数据监听
            statisticsWatcherId?.Cancel();
            revenueWatcherId?.Cancel();
            eatCodeWatcherId?.Cancel();
            reportWatcherId?.Cancel();
            oddsWatcherId?.Cancel();
            averageEatCodeWatcherId?.Cancel();
            maxLossLimitWatcherId?.Cancel();
        }
        #endregion
    }
} 